As funções de janela são um dos recursos mais poderosos do SQL para realizar cálculos analíticos complexos. Ao contrário das funções de agregação que consolidam várias linhas em um único resultado, as funções de janela permitem realizar cálculos em um conjunto de linhas relacionadas à linha atual—mantendo todas as linhas individuais no conjunto de resultados.
Esta lição apresenta os conceitos fundamentais das funções de janela e demonstra como elas podem transformar suas capacidades de análise de dados.
Uma função de janela realiza um cálculo em um conjunto de linhas de tabela que estão de alguma forma relacionadas à linha atual. Este conjunto de linhas é chamado de "janela" ou "quadro de janela". A principal diferença em relação às funções de agregação regulares é que as funções de janela não fazem com que as linhas sejam agrupadas em uma única linha de saída—cada linha mantém sua identidade.
Pense nisso como olhar através de uma janela em movimento enquanto você percorre seus dados. Para cada linha, você pode ver e calcular valores com base nas linhas relacionadas ao seu redor, mas cada linha ainda aparece separadamente no resultado.
Características principais:
OVERA sintaxe geral para uma função de janela é:
nome_funcao_janela(expressao) OVER (
[PARTITION BY expressao_particao]
[ORDER BY expressao_ordenacao]
[clausula_quadro_janela]
)
Componentes:
ROW_NUMBER, SUM, AVG)Vamos começar com uma das funções de janela mais comumente usadas: ROW_NUMBER(). Esta função atribui um número sequencial único a cada linha dentro de uma partição.
SELECT
payment_id,
customer_id,
amount,
payment_date,
ROW_NUMBER() OVER (ORDER BY payment_date) AS row_num
FROM
payment
LIMIT 10;
Esta consulta atribui um número sequencial a cada pagamento ordenado por data de pagamento. A cláusula OVER (ORDER BY payment_date) informa ao SQL para:
payment_dateO verdadeiro poder das funções de janela vem quando você usa PARTITION BY para criar janelas separadas para grupos diferentes:
SELECT
customer_id,
amount,
payment_date,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY payment_date
) AS payment_number
FROM
payment
WHERE
customer_id IN (1, 2, 3)
ORDER BY
customer_id,
payment_date;
Aqui está o que acontece:
PARTITION BY customer_id cria uma janela separada para cada clientepayment_dateROW_NUMBER() começa a contar a partir de 1 para cada novo clienteVisualização:
Cliente 1: Cliente 2: Cliente 3:
Linha 1 ----\ Linha 1 ----\ Linha 1 ----\
Linha 2 -----\ Linha 2 -----\ Linha 2 -----\
Linha 3 ------\ Linha 3 ------\ Linha 3 ------\
... ... ...
Cada cliente tem sua própria numeração de linhas independente.
As funções de janela facilitam a identificação do registro mais recente em cada grupo:
WITH numbered_payments AS (
SELECT
customer_id,
amount,
payment_date,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY payment_date DESC
) AS recency_rank
FROM
payment
)
SELECT
customer_id,
amount,
payment_date
FROM
numbered_payments
WHERE
recency_rank = 1
ORDER BY
customer_id
LIMIT 10;
Esta consulta encontra o pagamento mais recente para cada cliente:
recency_rank = 1 (o mais recente)As funções de janela também podem realizar agregações mantendo as linhas individuais:
SELECT
customer_id,
amount,
payment_date,
SUM(amount) OVER (PARTITION BY customer_id) AS total_spent,
AVG(amount) OVER (PARTITION BY customer_id) AS avg_payment,
amount - AVG(amount) OVER (PARTITION BY customer_id) AS diff_from_avg
FROM
payment
WHERE
customer_id IN (1, 2, 3)
ORDER BY
customer_id,
payment_date;
Para cada pagamento, esta consulta mostra:
Note como as funções de agregação regulares exigiriam um GROUP BY e consolidariam as linhas, mas as funções de janela permitem que você mantenha todos os detalhes enquanto adiciona contexto agregado.
É importante entender a diferença:
GROUP BY (Funções de Agregação):
SELECT
customer_id,
COUNT(*) AS payment_count,
SUM(amount) AS total_amount
FROM
payment
GROUP BY
customer_id;
Resultado: Uma linha por cliente
Funções de Janela:
SELECT
customer_id,
payment_id,
amount,
COUNT(*) OVER (PARTITION BY customer_id) AS payment_count,
SUM(amount) OVER (PARTITION BY customer_id) AS total_amount
FROM
payment;
Resultado: Cada linha de pagamento preservada, com valores agregados adicionados como colunas adicionais
ROW_NUMBER()).GROUP BY, as funções de janela não consolidam linhas—elas adicionam colunas calculadas aos seus dados existentes.Nas próximas lições, exploraremos mais funções de janela como RANK(), DENSE_RANK(), NTILE(), e mergulharemos mais profundamente em quadros de janela e cálculos analíticos avançados.